﻿using Abp.Application.Services;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Google.Protobuf;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
using SportsPlatform.Base;
using SportsPlatform.Consts;
using SportsPlatform.Dto.SportBusiness.CompetitionRuleInfo;
using SportsPlatform.Enums;
using SportsPlatform.Helpers;
using SportsPlatform.Model.SportBusiness;
using SportsPlatform.PermissionManagement.PermissionManagement;
using SportsPlatform.Query.SportBusiness.CompetitionRuleInfo;
using SportsPlatform.SportBusiness.ISportBusiness;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace SportsPlatform.SportBusiness.SportBusiness
{
    /// <summary>
    /// 
    /// </summary>
    [RemoteService(false)]  //隐藏自动生成的WebApi
    public class CompetitionRuleInfoService : SportsPlatformAppServiceBase, ICompetitionRuleInfoService
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly IRepository<CompetitionRuleInfo, Guid> _competitionRuleInfo;
        private readonly IRepository<RuleApplyProject, Guid> _ruleApplyProject;
        private readonly IRepository<Project, Guid> _project;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="competitionRuleInfo"></param>
        /// <param name="ruleApplyProject"></param>
        /// <param name="project"></param>
        public CompetitionRuleInfoService(IRepository<CompetitionRuleInfo, Guid> competitionRuleInfo
            , IRepository<RuleApplyProject, Guid> ruleApplyProject
            , IRepository<Project, Guid> project, IHttpContextAccessor context) : base(context)
        {
            _competitionRuleInfo = competitionRuleInfo;
            _ruleApplyProject = ruleApplyProject;
            _project = project;
        }
        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<PagePagingDto<CompetitionRuleInfoListDto>> GetCompetitionRuleInfoList(GetCompetitionRuleInfoListQuery Query)
        {
            try
            {
                var ruleInfoListDtos = await _competitionRuleInfo.GetAllListAsync(c => c.IsDeleted == false);
                var Dtos = ruleInfoListDtos.OrderByDescending(i => i.CreateTime).Skip(Query.PageSize * (Query.PageIndex - 1))
                   .Take(Query.PageSize)
                   .ToList();
                var ruleApplyProjects = await _ruleApplyProject.GetAllListAsync(c => c.IsDeleted == false);
                var projects = await _project.GetAllListAsync();
                List<CompetitionRuleInfoListDto> competitionRuleInfoListDto = new List<CompetitionRuleInfoListDto>();
                foreach (var item in Dtos)
                {
                    var ProjectList = ruleApplyProjects.Where(c => c.RuleID == item.Id);
                    var str = "";
                    if (ProjectList != null && ProjectList.Any())
                    {
                        var list = ProjectList.Select(c => c.ProjectID).ToList();
                        var proList = projects.Where(c => list.Contains(c.Id));
                        if (proList != null && proList.Any())
                        {
                            str = String.Join(",", proList.Select(c => c.Name).ToArray());
                        }
                    }
                    CompetitionRuleInfoListDto ruleInfoListDto = new CompetitionRuleInfoListDto()
                    {
                        Id = item.Id,
                        Name = item.Name,
                        Project = str,
                        Type = ((CompetitionRuleInfoTypeEnum)item.Type).GetDescription(),
                        Content = item.Content,
                        State = Enum.GetName(typeof(EnableAndDisableStateEnum), item.State),
                        CreateTime = item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
                    };
                    competitionRuleInfoListDto.Add(ruleInfoListDto);
                }
                return new PagePagingDto<CompetitionRuleInfoListDto>()
                {
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "查询成功",
                    Data = competitionRuleInfoListDto,
                    TotalCount = ruleInfoListDtos.Count,
                    TotalPage = 1
                };
            }
            catch (Exception ex)
            {
                return new PagePagingDto<CompetitionRuleInfoListDto>()
                {
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message,
                    Data = null,
                    TotalCount = 0,
                    TotalPage = 0
                };
            }
        }

        /// <summary>
        /// 添加比赛规则信息
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> AddCompetitionRuleInfo(AddCompetitionRuleInfoQuery Query)
        {
            try
            {
                #region 比赛规则信息
                CompetitionRuleInfo info = new CompetitionRuleInfo();
                info.parentId = Guid.Empty;
                info.Name = Query.Name;
                info.Type = (int)Query.Type;
                info.Content = Query.Content;
                info.State = (int)Query.State;
                info.FinalRule = (int)Query.FinalRule;
                info.FinalCircle = Query.FinalCircle;
                info.BestFiled = Query.BestFiled;
                info.PreliminaryRule = (int)Query.PreliminaryRule;
                info.LeakageRule = (int)Query.LeakageRule;
                info.OneLeakageNum = Query.OneLeakageNum;
                info.OneLeakageCircle = Query.OneLeakageCircle;
                info.TwoLeakageNum = Query.TwoLeakageNum;
                info.TwoLeakageType = (int)Query.TwoLeakageType;
                info.TwoLeakageCircle = Query.TwoLeakageCircle;
                info.TwoLeakageAddTime = Query.TwoLeakageAddTime;
                info.TwoLeakageThenNum = Query.TwoLeakageThenNum;
                info.TwoLeakageAddType = (int)Query.TwoLeakageAddType;
                info.TwoLeakageThenCircle = Query.TwoLeakageThenCircle;
                info.YellowCardNum = Query.YellowCardNum;
                info.YellowCardCircle = Query.YellowCardCircle;
                info.YellowCardTurnRedCardNum = Query.YellowCardTurnRedCardNum;
                info.TrunRedCardNum = Query.TrunRedCardNum;
                info.RedCardNum = Query.RedCardNum;
                info.FinalPeopleNum = Query.FinalPeopleNum;
                info.FinalDeductTime = Query.FinalDeductTime;
                info.SingleMinTime = Query.SingleMinTime;
                info.IsFirstCircled = Query.IsFirstCircled;
                info.Create(this._context);
                #endregion
                var guidId = await _competitionRuleInfo.InsertAndGetIdAsync(info);
                #region 适用项目
                if (Query.Project != null)
                {
                    foreach (var item in Query.Project)
                    {
                        RuleApplyProject rule = new RuleApplyProject()
                        {
                            RuleID = guidId,
                            ProjectID = item
                        };
                        rule.Create(this._context);
                        await _ruleApplyProject.InsertAsync(rule);
                    }
                }
                #endregion
                return new BaseResultDto()
                {
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "保存成功"
                };
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }

        /// <summary>
        /// 比赛规则信息详情
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<ResultDto<CompetitionRuleInfoDetailsDto>> CompetitionRuleInfoDetails(GetCompetitionRuleInfoDetailsQuery Query)
        {
            var ruleInfoListDtos = await _competitionRuleInfo.FirstOrDefaultAsync(Query.Id);
            var ruleApplyProjects = await _ruleApplyProject.GetAllListAsync(c => c.RuleID == Query.Id);
            var projects = await _project.GetAllListAsync();
            var str = "";
            var projectIds = new List<Guid>();
            if (ruleApplyProjects != null && ruleApplyProjects.Any())
            {
                var list = ruleApplyProjects.Select(c => c.ProjectID).ToList();
                var proList = projects.Where(c => list.Contains(c.Id));
                if (proList != null && proList.Any())
                {
                    str = String.Join(",", proList.Select(c => c.Name).ToArray());
                    projectIds = proList.Select(c => c.Id).ToArray().ToList();
                }
            }
            CompetitionRuleInfoDetailsDto ruleInfoListDto = new CompetitionRuleInfoDetailsDto()
            {
                ProjectIds = projectIds,
                Project = str,
                Name = ruleInfoListDtos.Name,
                Type = ruleInfoListDtos.Type,
                Content = ruleInfoListDtos.Content,
                State = ruleInfoListDtos.State,
                FinalRule = ruleInfoListDtos.FinalRule,
                FinalCircle = ruleInfoListDtos.FinalCircle,
                BestFiled = ruleInfoListDtos.BestFiled,
                PreliminaryRule = ruleInfoListDtos.PreliminaryRule,
                LeakageRule = ruleInfoListDtos.LeakageRule,
                OneLeakageNum = ruleInfoListDtos.OneLeakageNum,
                OneLeakageCircle = ruleInfoListDtos.OneLeakageCircle,
                TwoLeakageNum = ruleInfoListDtos.TwoLeakageNum,
                TwoLeakageType = ruleInfoListDtos.TwoLeakageType,
                TwoLeakageCircle = ruleInfoListDtos.TwoLeakageCircle,
                TwoLeakageAddTime = ruleInfoListDtos.TwoLeakageAddTime,
                TwoLeakageThenNum = ruleInfoListDtos.TwoLeakageThenNum,
                TwoLeakageAddType = ruleInfoListDtos.TwoLeakageAddType,
                TwoLeakageThenCircle = ruleInfoListDtos.TwoLeakageThenCircle,
                YellowCardNum = ruleInfoListDtos.YellowCardNum,
                YellowCardCircle = ruleInfoListDtos.YellowCardCircle,
                YellowCardTurnRedCardNum = ruleInfoListDtos.YellowCardTurnRedCardNum,
                TrunRedCardNum = ruleInfoListDtos.TrunRedCardNum,
                RedCardNum = ruleInfoListDtos.RedCardNum,
                FinalPeopleNum = ruleInfoListDtos.FinalPeopleNum,
                FinalDeductTime = ruleInfoListDtos.FinalDeductTime,
                SingleMinTime = ruleInfoListDtos.SingleMinTime,
                IsFirstCircled = ruleInfoListDtos.IsFirstCircled,
            };

            return new ResultDto<CompetitionRuleInfoDetailsDto>()
            {
                Data = ruleInfoListDto,
                IsSuccess = true,
                Code = (int)HttpResultCode.Success,
                Message = "保存成功"
            };
        }

        /// <summary>
        /// 修改比赛规则信息
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> UpdateCompetitionRuleInfo(UpdateCompetitionRuleInfoQuery Query)
        {
            try
            {
                #region 比赛规则信息
                CompetitionRuleInfo ruleInfo = await _competitionRuleInfo.FirstOrDefaultAsync(Query.Id);
                ruleInfo.Delete(this._context);
                await _competitionRuleInfo.UpdateAsync(ruleInfo);
                CompetitionRuleInfo info = new CompetitionRuleInfo();
                info.parentId = ruleInfo.parentId == Guid.Empty ? ruleInfo.Id : ruleInfo.parentId;
                info.Name = Query.Name;
                info.Type = (int)Query.Type;
                info.Content = Query.Content;
                info.State = (int)Query.State;
                info.FinalRule = (int)Query.FinalRule;
                info.FinalCircle = Query.FinalCircle;
                info.BestFiled = Query.BestFiled;
                info.PreliminaryRule = (int)Query.PreliminaryRule;
                info.LeakageRule = (int)Query.LeakageRule;
                info.OneLeakageNum = Query.OneLeakageNum;
                info.OneLeakageCircle = Query.OneLeakageCircle;
                info.TwoLeakageNum = Query.TwoLeakageNum;
                info.TwoLeakageType = (int)Query.TwoLeakageType;
                info.TwoLeakageCircle = Query.TwoLeakageCircle;
                info.TwoLeakageAddTime = Query.TwoLeakageAddTime;
                info.TwoLeakageThenNum = Query.TwoLeakageThenNum;
                info.TwoLeakageAddType = (int)Query.TwoLeakageAddType;
                info.TwoLeakageThenCircle = Query.TwoLeakageThenCircle;
                info.YellowCardNum = Query.YellowCardNum;
                info.YellowCardCircle = Query.YellowCardCircle;
                info.YellowCardTurnRedCardNum = Query.YellowCardTurnRedCardNum;
                info.TrunRedCardNum = Query.TrunRedCardNum;
                info.RedCardNum = Query.RedCardNum;
                info.FinalPeopleNum = Query.FinalPeopleNum;
                info.FinalDeductTime = Query.FinalDeductTime;
                info.SingleMinTime = Query.SingleMinTime;
                info.IsFirstCircled = Query.IsFirstCircled;

                info.Create(this._context);
                #endregion
                var guidId = await _competitionRuleInfo.InsertAndGetIdAsync(info);
                #region 适用项目
                if (Query.Project != null)
                {
                    foreach (var item in Query.Project)
                    {
                        RuleApplyProject rule = new RuleApplyProject()
                        {
                            RuleID = guidId,
                            ProjectID = item
                        };
                        rule.Create(this._context);
                        await _ruleApplyProject.InsertAsync(rule);
                    }
                }
                #endregion

                return new BaseResultDto()
                {
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "保存成功"
                };
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }


        /// <summary>
        /// 禁用启用比赛规则信息
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> UpdateCompetitionRuleInfoEnableOrDisable(UpdateCompetitionRuleInfoEnableOrDisableQuery Query)
        {
            try
            {
                #region 比赛规则信息
                CompetitionRuleInfo info = await _competitionRuleInfo.FirstOrDefaultAsync(Query.Id);
                #endregion
                if (info.State == (int)EnableAndDisableStateEnum.启用)
                {
                    info.State = (int)EnableAndDisableStateEnum.禁用;
                }
                else if (info.State == (int)EnableAndDisableStateEnum.禁用)
                {
                    info.State = (int)EnableAndDisableStateEnum.启用;
                }
                info.Update(this._context);
                await _competitionRuleInfo.UpdateAsync(info);
                return new BaseResultDto()
                {
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "成功" + (Enum.GetName(typeof(EnableAndDisableStateEnum), info.State))
                };
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }
    }
}
